<template>
  <div class="circle-progress-wrapper" :style="wrapperStyle" v-if="type === 'circle'">
    <el-progress 
      :type="type" 
      :percentage="currentPercentage" 
      :indeterminate="indeterminate" 
      :width="width" 
      :stroke-width="strokeWidth"
      :color="colorComputed"
      :status="status"
    >
      <template #default="{ percentage }" v-if="type === 'circle'">
        <slot :percentage="percentage">
          <span class="percentage-value" :style="textStyle">{{ Math.round(percentage) }}%</span>
        </slot>
      </template>
    </el-progress>
  </div>
  <el-progress
    v-if="type === 'line'"
    :stroke-width="strokeWidth"
    :percentage="currentPercentage"
    :color="colorComputed"
    :show-text="false"
  />
</template>

<script setup>
import { ref, onMounted, watch, computed } from 'vue'

const props = defineProps({
  percentage: {
    type: Number,
    default: 0,
    validator: (val) => val >= 0 && val <= 100
  },
  type: {
    type: String,
    default: 'circle',
    validator: (val) => ['circle', 'line'].includes(val)
  },
  indeterminate: {
    type: Boolean,
    default: false
  },
  width: {
    type: Number,
    default: 42
  },
  strokeWidth: {
    type: Number,
    default: 2
  },
  color: {
    type: [String, Array, Function],
    default: ''
  },
  duration: {
    type: Number,
    default: 1000 // 动画持续时间，默认1秒
  },
  immediate: {
    type: Boolean,
    default: true // 是否在组件挂载时立即开始动画
  },
  status: {
    type: String,
    default: '',
    validator: (val) => ['', 'success', 'exception', 'warning'].includes(val)
  },
  textColor: {
    type: String,
    default: ''
  },
  height: {
    type: [String, Number],
    default: '100%'
  },
  easing: {
    type: String,
    default: 'linear', // 动画缓动函数
    validator: (val) => ['linear', 'easeInOut', 'easeIn', 'easeOut'].includes(val)
  }
})

const currentPercentage = ref(0)

// 计算文本样式
const textStyle = computed(() => {
  return {
    color: props.textColor || 'var(--el-color-primary, #0C63FA)'
  }
})

// 计算容器样式
const wrapperStyle = computed(() => {
  return {
    height: typeof props.height === 'number' ? `${props.height}px` : props.height
  }
})

// 计算颜色
const colorComputed = computed(() => {
  if (props.color) return props.color
  
  // 默认颜色渐变
  return [
    { color: '#3644E0', percentage: 20 },
    { color: '#3B82F6', percentage: 40 },
    { color: '#0C63FA', percentage: 60 },
    { color: '#0C63FA', percentage: 80 },
    { color: '#0C63FA', percentage: 100 }
  ]
})

// 缓动函数
const easingFunctions = {
  linear: (t) => t,
  easeIn: (t) => t * t,
  easeOut: (t) => t * (2 - t),
  easeInOut: (t) => t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t
}

// 执行动画
const animateProgress = () => {
  const startTime = Date.now()
  const startValue = currentPercentage.value
  const endValue = props.percentage
  const duration = props.duration
  const easingFn = easingFunctions[props.easing]
  
  const updateValue = () => {
    const now = Date.now()
    const elapsed = now - startTime
    
    if (elapsed < duration) {
      // 使用缓动函数进行插值
      const progress = elapsed / duration
      const easedProgress = easingFn(progress)
      currentPercentage.value = startValue + (endValue - startValue) * easedProgress
      requestAnimationFrame(updateValue)
    } else {
      currentPercentage.value = endValue
    }
  }
  
  requestAnimationFrame(updateValue)
}

// 重置进度
const reset = () => {
  currentPercentage.value = 0
}

// 暴露方法给父组件
defineExpose({
  reset,
  animateProgress
})

// 监听percentage变化
watch(() => props.percentage, (newVal) => {
  animateProgress()
}, { deep: true })

// 组件挂载时启动动画
onMounted(() => {
  if (props.immediate) {
    animateProgress()
  }
})
</script>

<style scoped>
.circle-progress-wrapper {
  display: flex;
  justify-content: center;
  align-items: center;
  width: 100%;
}

.percentage-value {
  font-size: 12px;
  font-weight: 500;
}

:deep(.el-progress__text) {
  display: flex;
  justify-content: center;
  align-items: center;
  width: 100%;
  min-width: 0 !important;
  font-size: 12px !important;
}

:deep(.el-progress-circle) {
  transition: transform 0.3s ease;
}

:deep(.el-progress-circle:hover) {
  transform: scale(1.05);
}

:deep(.el-progress-circle__path) {
  transition: stroke-dasharray 0.6s ease;
}
</style> 